/**
 * Created by xinxinran on 15/12/1.
 */
'use strict';
var commonUtil = require('./commonUtil');

class GomokuGamer{
    constructor(room){
        this.gameRoom = room;

        this.p1Color = 0;
        this.p2Color = 0;

        this.nowColor = 0;
        this.nowToken = null;

        this.positions = [];
        this.positionsObj = {};

        this.positionStep = [];

        this.requestToken = null;
    }

    initRoomRule(){
        this.p1Color = 1;
        this.p2Color = 2;

        this.nowColor = 0;

        this.positions = [];
        this.positionsObj = {};
        this.positionStep = [];

        this.requestToken = null;
    }

    startGame(){
        var _this = this;
        this.nowColor = 1;
        this.gameRoom.firstPlayer.sendGameCommand('gameStart', {mode : _this.p1Color, nowColor : _this.nowColor});
        this.gameRoom.secondPlayer.sendGameCommand('gameStart', {mode : _this.p2Color, nowColor : _this.nowColor});

        this.positions = [];
        this.positionsObj = {};
        this.positionStep = [];
        this.requestToken = null;
        this.sendToken();
    }

    sendToken(){
        this.nowToken = commonUtil.uuid(16, 16);
        if(this.nowColor === this.p1Color){
            this.gameRoom.firstPlayer.sendGameCommand('putToken', this.nowToken);
        }else{
            this.gameRoom.secondPlayer.sendGameCommand('putToken', this.nowToken);
        }
    }

    getChess(x, y, t){
        var m, p = y * 15 + x, w, _this = this;
        if(this.nowToken !== t || this.positions[p] || this.requestToken){
            return;
        }

        this.nowToken = null;
        m = this.nowColor;
        this.positions[p] = m;
        this.positionsObj[x + '|' + y] = m;
        this.positionStep.push([x, y, m]);

        commonUtil.each(this.gameRoom.roomClients, function(sId, client){
            client.sendGameCommand('putChess', {x : x, y : y, nowColor : m});
        }, this);

        if(this.checkGridFive(x, y)){
            if(this.p1Color === m){
                this.endRound(1);
            }else{
                this.endRound(2);
            }
        }else{
            this.nowColor = this.nowColor ^ 3;
            this.sendToken();

            commonUtil.each(this.gameRoom.roomClients, function(sId, client){
                client.notifyPlayerStatus(_this.gameRoom);
            }, this);
        }
    }

    backChess(backer){
        var lastChessInfo, p, x, y, _this = this;

        if(!this.positionStep.length){
            return;
        }

        lastChessInfo = this.positionStep.pop();

        if(lastChessInfo[2] === backer){
            x = lastChessInfo[0];
            y = lastChessInfo[1];
            p = y * 15 + x;
            this.positions[p] = null;
            this.positionsObj[x + '|' + y] = null;

            this.nowColor = this.nowColor ^ 3;
            this.sendToken();

            commonUtil.each(this.gameRoom.roomClients, function(sId, client){
                client.sendGameCommand('delChess', {x : x, y : y, last : _this.positionStep[_this.positionStep.length - 1]});
                client.notifyPlayerStatus(_this.gameRoom);
            }, this);
        }
    }

    endRound(winner){
        var room = this.gameRoom, content;
        if(winner === 1){
            room.firstPlayer.updateResult(1);
            room.secondPlayer.updateResult(-1);
            room.roomP1Scroe++;

            content = room.firstPlayer.username + '胜!';
        }else if(winner === 2){
            room.firstPlayer.updateResult(-1);
            room.secondPlayer.updateResult(1);
            room.roomP2Score++;
            content = room.secondPlayer.username + '胜!';
        }else{
            room.firstPlayer.updateResult(0);
            room.secondPlayer.updateResult(0);

            content = '双方平局!';
        }

        room.firstPlayer.statusDesc = '';
        room.secondPlayer.statusDesc = '';

        commonUtil.each(room.roomClients, function(sId, client){
            client.notifyPlayerStatus(room);
            client.sendNotice('胜负已定', content, 'success');
        }, this);

        this.nextRound();
    }

    nextRound(){
        var room = this.gameRoom;
        room.p1Status = 0;
        room.p2Status = 0;

        this.p1Color = this.p1Color ^ 3;
        this.p2Color = this.p2Color ^ 3;

        this.nowColor = 0;
        this.nowToken = null;
        this.requestToken = null;

        this.positions = [];
        this.positionsObj = {};
        this.positionStep = [];
    }

    //XXX : 烂代码就是需要优化
    checkGridFive(x, y){
        var  p = y * 15 + x, m = this.positions[p], matchLen = 1, tx, ty, result = [];
        //判断方向:横
        tx = x;
        ty = y;
        while(tx >= 0){
            tx--;
            if(m === this.positions[ty * 15 + tx]){
                matchLen++;
            }else{
                break;
            }
        }
        tx = x;
        while(tx < 15){
            tx++;
            if(m === this.positions[ty * 15 + tx]){
                matchLen++;
            }else{
                break;
            }
        }

        result.push(matchLen);
        matchLen = 1;

        //判断方向:竖
        tx = x;
        ty = y;
        while(ty >= 0){
            ty--;
            if(m === this.positions[ty * 15 + tx]){
                matchLen++;
            }else{
                break;
            }
        }
        ty = y;
        while(ty < 15){
            ty++;
            if(m === this.positions[ty * 15 + tx]){
                matchLen++;
            }else{
                break;
            }
        }

        result.push(matchLen);
        matchLen = 1;

        //判断方向:反斜
        tx = x;
        ty = y;
        while(ty > 0 && tx > 0 && ty < 15 && tx < 15){
            ty--;
            tx--;
            if(m === this.positions[ty * 15 + tx]){
                matchLen++;
            }else{
                break;
            }
        }
        tx = x;
        ty = y;
        while(ty >= 0 && tx >= 0 && ty < 15 && tx < 15){
            ty++;
            tx++;
            if(m === this.positions[ty * 15 + tx]){
                matchLen++;
            }else{
                break;
            }
        }
        result.push(matchLen);
        matchLen = 1;

        //判断方向:正斜
        tx = x;
        ty = y;
        while(ty > 0 && tx > 0 && ty < 15 && tx < 15){
            ty--;
            tx++;
            if(m === this.positions[ty * 15 + tx]){
                matchLen++;
            }else{
                break;
            }
        }
        tx = x;
        ty = y;
        while(ty >= 0 && tx >= 0 && ty < 15 && tx < 15){
            ty++;
            tx--;
            if(m === this.positions[ty * 15 + tx]){
                matchLen++;
            }else{
                break;
            }
        }
        result.push(matchLen);

        return ~result.indexOf(5);
    }

}

module.exports = GomokuGamer;